<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/qs/6.10.1/qs.min.js"></script>
  </head>
  <body>
    <h1>第一种取消</h1>
    <button id="btn">发起请求接口</button>
    <button id="btn2">手动关闭请求接口</button>
    <h1>第二种取消</h1>
    <button id="btn3">发起请求接口2</button>
    <button id="btn4">手动关闭请求接口2</button>
    <h1>第三种取消</h1>
    <button id="btn5">取消请求接口(请求)3</button>
  </body>
  <script>
    axios.defaults.baseURL = 'http://localhost:8000';
    //第一种取消接口请求 通过  axios.CancelToken   axios.CancelToken.source()
    let CancelToken = axios.CancelToken;
    let source = CancelToken.source();
    btn.addEventListener(
      'click',
      function () {
        axios
          .get('/cancelRequst', {
            cancelToken: source.token,
          })
          .catch(function (thrown) {
            if (axios.isCancel(thrown)) {
              console.log('Request canceled', thrown.message);
            } else {
              // 处理错误
            }
          });
      },
      false
    );
    btn2.addEventListener(
      'click',
      function () {
        source.cancel('Operation canceled by the user.');
      },
      false
    );

    //第二种取消
    var CancelToken2 = axios.CancelToken;
    var cancel2;
    btn3.addEventListener(
      'click',
      function () {
        axios.get('/cancelRequst', {
          cancelToken: new CancelToken(function (c) {
            cancel2 = c;
          }),
        });
      },
      false
    );
    btn4.addEventListener(
      'click',
      function () {
        cancel2();
      },
      false
    );

    //第三种取消  也会用于取消重复接口
    let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
    let cancelToken = axios.CancelToken;
    let removePending = (ever) => {
      for (let p in pending) {
        if (pending[p].u === ever.url + '&' + ever.method) {
          //当当前请求在数组中存在时执行函数体
          pending[p].f(); //执行取消操作
          pending.splice(p, 1); //把这条记录从数组中移除
        }
      }
    };
    const service = axios.create({
      timeout: 30000,
      retry: 1, // 请求次数
    });
    service.interceptors.request.use(
      (config) => {
        removePending(config);
        config.cancelToken = new cancelToken((c) => {
          // 这里的ajax标识我是用请求地址&请求方式拼接的字符串，当然你可以选择其他的一些方式
          pending.push({ u: config.url + '&' + config.method, f: c });
        });
        return config;
      },
      (error) => {}
    );

    service.interceptors.response.use(
      (res) => {
        removePending(res.config); //在一个ajax响应后再执行一下取消操作，把已经完成的请求从pending中移除
        return res;
      },
      (err) => {
        console.log(err);
      }
    );
    btn5.addEventListener(
      'click',
      function () {
        service({
          url: '/cancelRequst',
          method: 'GET',
        });
      },
      false
    );
  </script>
</html>
